function mxVertexHandler(a) {
    if (a != null) {
        this.state = a;
        this.init()
    }
}
mxVertexHandler.prototype.graph = null;
mxVertexHandler.prototype.state = null;
mxVertexHandler.prototype.singleSizer = !1;
mxVertexHandler.prototype.index = null;
mxVertexHandler.prototype.allowHandleBoundsCheck = !0;
mxVertexHandler.prototype.crisp = !0;
mxVertexHandler.prototype.handleImage = null;
mxVertexHandler.prototype.tolerance = 0;
mxVertexHandler.prototype.init = function() {
    this.graph = this.state.view.graph;
    this.selectionBounds = this.getSelectionBounds(this.state);
    this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
    this.selectionBorder = this.createSelectionShape(this.bounds);
    this.selectionBorder.dialect = this.graph.dialect != mxConstants.DIALECT_SVG ? mxConstants.DIALECT_VML: mxConstants.DIALECT_SVG;
    this.selectionBorder.init(this.graph.getView().getOverlayPane());
    this.selectionBorder.dialect == mxConstants.DIALECT_SVG ? this.selectionBorder.node.setAttribute("pointer-events", "none") : this.selectionBorder.node.style.background = "";
    if (this.graph.isCellMovable(this.state.cell)) this.selectionBorder.node.style.cursor = mxConstants.CURSOR_MOVABLE_VERTEX;
    mxEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state);
    if (mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells) {
        var a = this.graph.isCellResizable(this.state.cell);
        this.sizers = [];
        if (a || this.graph.isLabelMovable(this.state.cell) && this.state.width >= 2 && this.state.height >= 2) {
            var b = 0;
            if (a) {
//            	强制取消可缩放功能
//                if (!this.singleSizer) {
//                    this.sizers.push(this.createSizer("nw-resize", b++));
//                    this.sizers.push(this.createSizer("n-resize", b++));
//                    this.sizers.push(this.createSizer("ne-resize", b++));
//                    this.sizers.push(this.createSizer("w-resize", b++));
//                    this.sizers.push(this.createSizer("e-resize", b++));
//                    this.sizers.push(this.createSizer("sw-resize", b++));
//                    this.sizers.push(this.createSizer("s-resize", b++))
//                }
                //this.sizers.push(this.createSizer("se-resize", b++))
            }
            a = this.graph.model.getGeometry(this.state.cell);
            if (a != null && !a.relative && !this.graph.isSwimlane(this.state.cell) && this.graph.isLabelMovable(this.state.cell)) {
                this.labelShape = this.createSizer(mxConstants.CURSOR_LABEL_HANDLE, mxEvent.LABEL_HANDLE, mxConstants.LABEL_HANDLE_SIZE, mxConstants.LABEL_HANDLE_FILLCOLOR);
                this.sizers.push(this.labelShape)
            }
        } else if (this.graph.isCellMovable(this.state.cell) && !this.graph.isCellResizable(this.state.cell) && this.state.width < 2 && this.state.height < 2) {
            this.labelShape = this.createSizer(mxConstants.CURSOR_MOVABLE_VERTEX, null, null, mxConstants.LABEL_HANDLE_FILLCOLOR);
            this.sizers.push(this.labelShape)
        }
    }
    this.redraw()
};
mxVertexHandler.prototype.getSelectionBounds = function(a) {
    return new mxRectangle(a.x, a.y, a.width, a.height)
};
mxVertexHandler.prototype.createSelectionShape = function(a) {
    a = new mxRectangleShape(a, null, this.getSelectionColor());
    a.strokewidth = this.getSelectionStrokeWidth();
    a.isDashed = this.isSelectionDashed();
    a.crisp = this.crisp;
    return a
};
mxVertexHandler.prototype.getSelectionColor = function() {
    return mxConstants.VERTEX_SELECTION_COLOR
};
mxVertexHandler.prototype.getSelectionStrokeWidth = function() {
    return mxConstants.VERTEX_SELECTION_STROKEWIDTH
};
mxVertexHandler.prototype.isSelectionDashed = function() {
    return mxConstants.VERTEX_SELECTION_DASHED
};
mxVertexHandler.prototype.createSizer = function(a, b, c, d) {
    c = c || mxConstants.HANDLE_SIZE;
    c = this.createSizerShape(new mxRectangle(0, 0, c, c), b, d);
    if (this.state.text != null && this.state.text.node.parentNode == this.graph.container) {
        c.bounds.height = c.bounds.height - 1;
        c.bounds.width = c.bounds.width - 1;
        c.dialect = mxConstants.DIALECT_STRICTHTML;
        c.init(this.graph.container)
    } else {
        c.dialect = this.graph.dialect != mxConstants.DIALECT_SVG ? mxConstants.DIALECT_VML: mxConstants.DIALECT_SVG;
        c.init(this.graph.getView().getOverlayPane())
    }
    mxEvent.redirectMouseEvents(c.node, this.graph, this.state);
    if (this.graph.isEnabled()) c.node.style.cursor = a;
    if (!this.isSizerVisible(b)) c.node.style.visibility = "hidden";
    return c
};
mxVertexHandler.prototype.isSizerVisible = function() {
    return true
};
mxVertexHandler.prototype.createSizerShape = function(a, b, c) {
    if (this.handleImage != null) {
        a.width = this.handleImage.width;
        a.height = this.handleImage.height;
        return new mxImageShape(a, this.handleImage.src)
    }
    a = new mxRectangleShape(a, c || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
    a.crisp = this.crisp;
    return a
};
mxVertexHandler.prototype.moveSizerTo = function(a, b, c) {
    if (a != null) {
        a.bounds.x = b - a.bounds.width / 2;
        a.bounds.y = c - a.bounds.height / 2;
        a.redraw()
    }
};
mxVertexHandler.prototype.getHandleForEvent = function(a) {
    if (a.isSource(this.labelShape)) return mxEvent.LABEL_HANDLE;
    if (this.sizers != null) for (var b = this.tolerance,
    b = this.allowHandleBoundsCheck && (mxClient.IS_IE || b > 0) ? new mxRectangle(a.getGraphX() - b, a.getGraphY() - b, 2 * b, 2 * b) : null, c = 0; c < this.sizers.length; c++) if (a.isSource(this.sizers[c]) || b != null && this.sizers[c].node.style.visibility != "hidden" && mxUtils.intersects(this.sizers[c].bounds, b)) return c;
    return null
};
mxVertexHandler.prototype.mouseDown = function(a, b) {
    if (!b.isConsumed() && this.graph.isEnabled() && !this.graph.isForceMarqueeEvent(b.getEvent()) && (this.tolerance > 0 || b.getState() == this.state)) {
        var c = this.getHandleForEvent(b);
        if (c != null) {
            this.start(b.getX(), b.getY(), c);
            b.consume()
        }
    }
};
mxVertexHandler.prototype.start = function(a, b, c) {
    a = mxUtils.convertPoint(this.graph.container, a, b);
    this.startX = a.x;
    this.startY = a.y;
    this.index = c;
    this.selectionBorder.node.style.visibility = "hidden";
    this.preview = this.createSelectionShape(this.bounds);
    if (this.state.text != null && this.state.text.node.parentNode == this.graph.container) {
        this.preview.dialect = mxConstants.DIALECT_STRICTHTML;
        this.preview.init(this.graph.container)
    } else {
        this.preview.dialect = this.graph.dialect != mxConstants.DIALECT_SVG ? mxConstants.DIALECT_VML: mxConstants.DIALECT_SVG;
        this.preview.init(this.graph.view.getOverlayPane())
    }
};
mxVertexHandler.prototype.mouseMove = function(a, b) {
    if (!b.isConsumed() && this.index != null) {
        var c = new mxPoint(b.getGraphX(), b.getGraphY()),
        d = this.graph.isGridEnabledEvent(b.getEvent()),
        e = this.graph.getView().scale;
        if (this.index == mxEvent.LABEL_HANDLE) {
            if (d) {
                c.x = this.graph.snap(c.x / e) * e;
                c.y = this.graph.snap(c.y / e) * e
            }
            this.moveSizerTo(this.sizers[this.sizers.length - 1], c.x, c.y);
            b.consume()
        } else if (this.index != null) {
            this.bounds = this.union(this.selectionBounds, c.x - this.startX, c.y - this.startY, this.index, d, e, this.graph.view.translate);
            this.drawPreview();
            b.consume()
        }
    } else this.getHandleForEvent(b) != null && b.consume(false)
};
mxVertexHandler.prototype.mouseUp = function(a, b) {
    if (!b.isConsumed() && this.index != null && this.state != null) {
        var c = new mxPoint(b.getGraphX(), b.getGraphY()),
        d = this.graph.getView().scale,
        e = this.graph.isGridEnabledEvent(b.getEvent());
        this.resizeCell(this.state.cell, (c.x - this.startX) / d, (c.y - this.startY) / d, this.index, e);
        this.reset();
        b.consume()
    }
};
mxVertexHandler.prototype.reset = function() {
    this.index = null;
    if (this.preview != null) {
        this.preview.destroy();
        this.preview = null
    }
    if (this.selectionBorder != null) {
        this.selectionBounds = this.getSelectionBounds(this.state);
        this.selectionBorder.node.style.visibility = "visible";
        this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
        this.drawPreview()
    }
};
mxVertexHandler.prototype.resizeCell = function(a, b, c, d, e) {
    var f = this.graph.model.getGeometry(a);
    if (d == mxEvent.LABEL_HANDLE) {
        c = this.graph.view.scale;
        b = (this.labelShape.bounds.getCenterX() - this.startX) / c;
        c = (this.labelShape.bounds.getCenterY() - this.startY) / c;
        f = f.clone();
        if (f.offset == null) f.offset = new mxPoint(b, c);
        else {
            f.offset.x = f.offset.x + b;
            f.offset.y = f.offset.y + c
        }
        this.graph.model.setGeometry(a, f)
    } else {
        b = this.union(f, b, c, d, e, 1, new mxPoint(0, 0));
        this.graph.resizeCell(a, b)
    }
};
mxVertexHandler.prototype.union = function(a, b, c, d, e, f, g) {
    if (this.singleSizer) {
        var g = a.x + a.width + b,
        h = a.y + a.height + c;
        if (e) {
            g = this.graph.snap(g / f) * f;
            h = this.graph.snap(h / f) * f
        }
        f = new mxRectangle(a.x, a.y, 0, 0);
        f.add(new mxRectangle(g, h, 0, 0));
        return f
    }
    var h = a.x - g.x * f,
    k = h + a.width,
    i = a.y - g.y * f,
    a = i + a.height;
    if (d > 4) {
        a = a + c;
        e && (a = this.graph.snap(a / f) * f)
    } else if (d < 3) {
        i = i + c;
        e && (i = this.graph.snap(i / f) * f)
    }
    if (d == 0 || d == 3 || d == 5) {
        h = h + b;
        e && (h = this.graph.snap(h / f) * f)
    } else if (d == 2 || d == 4 || d == 7) {
        k = k + b;
        e && (k = this.graph.snap(k / f) * f)
    }
    e = k - h;
    a = a - i;
    if (e < 0) {
        h = h + e;
        e = Math.abs(e)
    }
    if (a < 0) {
        i = i + a;
        a = Math.abs(a)
    }
    return new mxRectangle(h + g.x * f, i + g.y * f, e, a)
};
mxVertexHandler.prototype.redraw = function() {
    this.selectionBounds = this.getSelectionBounds(this.state);
    this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
    if (this.sizers != null) {
        var a = this.state,
        b = a.x + a.width,
        c = a.y + a.height;
        if (this.singleSizer) this.moveSizerTo(this.sizers[0], b, c);
        else {
            var d = a.x + a.width / 2,
            e = a.y + a.height / 2;
            if (this.sizers.length > 1) {
                this.moveSizerTo(this.sizers[0], a.x, a.y);
                this.moveSizerTo(this.sizers[1], d, a.y);
                this.moveSizerTo(this.sizers[2], b, a.y);
                this.moveSizerTo(this.sizers[3], a.x, e);
                this.moveSizerTo(this.sizers[4], b, e);
                this.moveSizerTo(this.sizers[5], a.x, c);
                this.moveSizerTo(this.sizers[6], d, c);
                this.moveSizerTo(this.sizers[7], b, c);
                this.moveSizerTo(this.sizers[8], d + a.absoluteOffset.x, e + a.absoluteOffset.y)
            } else this.state.width >= 2 && this.state.height >= 2 ? this.moveSizerTo(this.sizers[0], d + a.absoluteOffset.x, e + a.absoluteOffset.y) : this.moveSizerTo(this.sizers[0], a.x, a.y)
        }
    }
    this.drawPreview()
};
mxVertexHandler.prototype.drawPreview = function() {
    if (this.preview != null) {
        this.preview.bounds = this.bounds;
        if (this.preview.node.parentNode == this.graph.container) {
            this.preview.bounds.width = Math.max(0, this.preview.bounds.width - 1);
            this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1)
        }
        this.preview.redraw()
    }
    this.selectionBorder.bounds = this.bounds;
    this.selectionBorder.redraw()
};
mxVertexHandler.prototype.destroy = function() {
    if (this.preview != null) {
        this.preview.destroy();
        this.preview = null
    }
    this.selectionBorder.destroy();
    this.labelShape = this.selectionBorder = null;
    if (this.sizers != null) for (var a = 0; a < this.sizers.length; a++) {
        this.sizers[a].destroy();
        this.sizers[a] = null
    }
};